package cn.tedu.core;

import cn.tedu.vo.BeanDefinition;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**基于XML文件来存储核心对象的容器类
 * @Autohor:Jason
 */
public class ClassPathXMLApplicationCntext {
    /**
     * 核心上下文配置文件路径
     */
    private String contextConfigLocation;
    /**
     * 实例map
     */
    private Map<String,Object> instanceMap = new HashMap<>();
    /**
     * 管理bean定义信息的map
     */
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();

    /**
     * 读取xml文件新信息把它赋值给BeanDefinition然后再存入BeanDefinitionMap中
     * 把非懒加载的对象放入instanceMap中
     */
    public ClassPathXMLApplicationCntext(){
        this.contextConfigLocation = "classpath:spring-config.xml";
        //此方法用于初始化bean定义map
        initBeanMap();
        //以上完成后,把非懒加载的对象放入instanceMap中
        initInstanceMap();
    }
    public ClassPathXMLApplicationCntext(String path){
        this.contextConfigLocation = path;
        //此方法用于初始化bean定义map
        initBeanMap();
        //以上完成后,把非懒加载的对象放入instanceMap中
        initInstanceMap();
    }

    private void initBeanMap() {
    }

    private void initInstanceMap() {
        InputStream in = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);
        //在此之前请去pom.xml添加DMO4J依赖

        try {
            SAXReader saxReader = new SAXReader();
            Document doc = saxReader.read(in);
            Element rootElement = doc.getRootElement();
            List<Element> elements = rootElement.elements();
            for (Element e : elements){
                String id = e.attributeValue("id");
                Boolean lazy = Boolean.parseBoolean(e.attributeValue("lazy"));
                String pageClass = e.attributeValue("pageClass");
                BeanDefinition beanDefinition = new BeanDefinition(id,lazy,pageClass);
                beanDefinitionMap.put(id,beanDefinition);
                if(!lazy){
                    //通过反射实例对象,然后再添加到实例map中
                    Object o = newInstance(pageClass);
                    instanceMap.put(id,o);
                }

            }
            System.out.println("bean定义map:"+ beanDefinitionMap);
            System.out.println("bean实例map:"+instanceMap);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    private Object newInstance(String pageClass) {
        try{
            Class<?> aClass = Class.forName(pageClass);
            Object o = aClass.newInstance();
            return o;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public Object getBean(String key){
        //先判断bean实例map是否存在
        Object o = instanceMap.get(key);
        if (o==null) {
            //再判断定义map是否有
            BeanDefinition beanDefinition = beanDefinitionMap.get(key);
            if(beanDefinition!=null){
                o = newInstance(beanDefinition.getPageClass());
                instanceMap.put(beanDefinition.getId(),o);
            }
        }
        return o;
    }
    public <T>T getBean(String key,Class<T> tClass){
        Object bean = getBean(key);
        return (T)bean;
    }
    public static void main(String[] args) {
        ClassPathXMLApplicationCntext ac = new ClassPathXMLApplicationCntext("beans.xml");
        Object date1 = ac.getBean("date1");
//        Date date11 = ac.getBean("date11", Date.class);
        System.out.println(date1);
//        System.out.println(date11);
    }

}
